#include "Stdafx.h"
#include "ConstantBufferData.h"

namespace WindGE
{
	ConstantBufferData::ConstantBufferData(const std::string& name)
		: name_(name)
		, data_(nullptr)
		, size_(0)
	{
	}

	ConstantBufferData::~ConstantBufferData()
	{
		safe_delete(data_);
	}

	void ConstantBufferData::attach(const std::string& n, void* data, unsigned int size)
	{
		if (!data_ && size_ == 0)
		{
			data_ = malloc(size);
		}
		else
		{
			data_ = realloc(data_, size_ + size);
		}
		memcpy((void*)((char*)data_ + size_), data, size);

		Variable var(size_, size);
		var_list_.insert(std::pair<std::string, Variable>(n, var));

		size_ += size;
	}

	void ConstantBufferData::attach(const std::string& n, bool var)
	{
		attach(n, &var, sizeof(bool));
	}

	void ConstantBufferData::attach(const std::string& n, int var)
	{
		attach(n, &var, sizeof(int));
	}

	void ConstantBufferData::attach(const std::string& n, unsigned int var)
	{
		attach(n, &var, sizeof(unsigned int));
	}

	void ConstantBufferData::attach(const std::string& n, float var)
	{
		attach(n, &var, sizeof(float));
	}

	void ConstantBufferData::attach(const std::string& n, const XMFLOAT2& var)
	{
		attach(n, (void*)(&var), sizeof(XMFLOAT2));
	}

	void ConstantBufferData::attach(const std::string& n, const XMFLOAT3& var)
	{
		attach(n, (void*)(&var), sizeof(XMFLOAT3));
	}

	void ConstantBufferData::attach(const std::string& n, const XMFLOAT4& var)
	{
		attach(n, (void*)(&var), sizeof(XMFLOAT4));
	}

	void ConstantBufferData::attach(const std::string& n, const XMFLOAT4X4& var)
	{
		attach(n, (void*)(&var), sizeof(XMFLOAT4X4));
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<int>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(int)*var.size());
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<unsigned int>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(unsigned int)*var.size());
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<float>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(float)*var.size());
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<XMFLOAT2>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(XMFLOAT2)*var.size());
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<XMFLOAT3>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(XMFLOAT3)*var.size());
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<XMFLOAT4>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(XMFLOAT4)*var.size());
	}

	void ConstantBufferData::attach(const std::string& n, const std::vector<XMFLOAT4X4>& var)
	{
		attach(n, (void*)(&var[0]), sizeof(XMFLOAT4X4)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, void* data, unsigned int size)
	{
		static std::unordered_map<std::string, Variable>::iterator iter;
		iter = var_list_.find(n);
		if (iter == var_list_.end()) return;

		memcpy((void*)((char*)data_ + iter->second.offset), data, size);
	}

	void ConstantBufferData::set(const std::string& n, bool var)
	{
		set(n, &var, sizeof(bool));
	}

	void ConstantBufferData::set(const std::string& n, int var)
	{
		set(n, &var, sizeof(int));
	}

	void ConstantBufferData::set(const std::string& n, unsigned int var)
	{
		set(n, &var, sizeof(unsigned int));
	}

	void ConstantBufferData::set(const std::string& n, float var)
	{
		set(n, &var, sizeof(float));
	}

	void ConstantBufferData::set(const std::string& n, const XMFLOAT2& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT2));
	}

	void ConstantBufferData::set(const std::string& n, const XMFLOAT3& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT3));
	}

	void ConstantBufferData::set(const std::string& n, const XMFLOAT4& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT4));
	}

	void ConstantBufferData::set(const std::string& n, const XMFLOAT4X4& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT4X4));
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<int>& var)
	{
		set(n, (void*)(&var), sizeof(int)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<unsigned int>& var)
	{
		set(n, (void*)(&var), sizeof(unsigned int)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<float>& var)
	{
		set(n, (void*)(&var), sizeof(float)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<XMFLOAT2>& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT2)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<XMFLOAT3>& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT3)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<XMFLOAT4>& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT4)*var.size());
	}

	void ConstantBufferData::set(const std::string& n, const std::vector<XMFLOAT4X4>& var)
	{
		set(n, (void*)(&var), sizeof(XMFLOAT4X4)*var.size());
	}

}//end namespace WindGE


